package com.atguigu.tingshu.user.service.impl;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.plugin.auth.constant.Constants;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.common.util.MongoUtil;
import com.atguigu.tingshu.model.user.UserListenProcess;
import com.atguigu.tingshu.user.service.UserListenProcessService;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.atguigu.tingshu.vo.user.LastUserListenPlayVo;
import com.atguigu.tingshu.vo.user.UserListenProcessVo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserListenProcessServiceImpl implements UserListenProcessService {

	@Autowired
	private MongoTemplate mongoTemplate;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private KafkaService kafkaService;


	@Override
	public void userListenProcessVo(UserListenProcessVo userListenProcessVo) {
		/*
		 * 声音的播放进度用什么技术存储 redis mysql mongodb
		 * 声音的播放进度数据特点:数据量大,数据价值不高
		 * 所以我们用mongodb
		 *
		 * 把存储的数据 存储到集中中 选一个策略 都保存到一个集合,数据太大 读写效率慢
		 * 所以我们要用分集合的方法
		 *	1,根据用户的id进行拆分  一个用户一个集合 弊端太多了
		 * 	2,固定集合数据:   假设一个核定的集合数量 每个集合都有索引
		 * */

		Long userId  = AuthContextHolder.getUserId();

		//创建集合
		String connectionName = MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS,userId);

		//创建Cri对象
		Criteria criteria = Criteria.where("albumId").is(userListenProcessVo.getAlbumId())
				.and("trackId").is(userListenProcessVo.getTrackId())
				.and("userId").is(userId);

		//创建query对象
		Query query = Query.query(criteria);

		UserListenProcess userListenProcess = mongoTemplate.findOne(query, UserListenProcess.class,connectionName);


		if(userListenProcess==null){
			//插入的数据是声音播放进度的数据
			userListenProcess = new UserListenProcess();
			userListenProcess.setUserId(userId);
			userListenProcess.setAlbumId(userListenProcessVo.getAlbumId());
			userListenProcess.setTrackId(userListenProcessVo.getTrackId());
			userListenProcess.setBreakSecond(userListenProcessVo.getBreakSecond());
			userListenProcess.setCreateTime(new Date());
			userListenProcess.setUpdateTime(new Date());

			mongoTemplate.insert(userListenProcess,connectionName);
		}else{
			//如果可以查询到数据 就修改
			userListenProcess.setBreakSecond(userListenProcessVo.getBreakSecond());
			userListenProcess.setUpdateTime(new Date());
			mongoTemplate.save(userListenProcess,connectionName);
		}
		// 构建Redis的key
		Date date = new Date() ;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd") ;
		String dateFormat = simpleDateFormat.format(date);
		String redisKey = "track:play:" + userListenProcessVo.getTrackId() + ":" + dateFormat + ":" + userId ;
		Boolean hasKey = redisTemplate.hasKey(redisKey);
		if(!hasKey) {		// 不存在key，就说明是第一次进行播放

			// 向Kafka中发送更新播放量的消息
			TrackStatMqVo trackStatMqVo = new TrackStatMqVo();
			trackStatMqVo.setBusinessNo(UUID.randomUUID().toString().replace("-" , ""));
			trackStatMqVo.setAlbumId(userListenProcessVo.getAlbumId());
			trackStatMqVo.setTrackId(userListenProcessVo.getTrackId());
			trackStatMqVo.setStatType(SystemConstant.ALBUM_STAT_PLAY);
			trackStatMqVo.setCount(1);


			kafkaService.sendMessage(KafkaConstant.QUEUE_TRACK_STAT_UPDATE , JSON.toJSONString(trackStatMqVo) );

			// 向Redis中存储key
			redisTemplate.opsForValue().set(redisKey , "1" , 1 , TimeUnit.DAYS);

		}

	}

	@Override
	public BigDecimal getTrackBreakSecond(Long trackId) {

		// 获取当前登录用户的id
		Long userId = AuthContextHolder.getUserId();

		// 获取集合名称
		String collectionName = MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId);

		// 构建查询条件对象，根据用户的id和声音的id进行查找
		Criteria criteria = Criteria.where("userId").is(userId).and("trackId").is(trackId);
		Query query = Query.query(criteria);

		// 根据用户的id和声音的id进行查找
		UserListenProcess userListenProcess = mongoTemplate.findOne(query, UserListenProcess.class, collectionName);

		// 判断
		if (userListenProcess != null) {
			return userListenProcess.getBreakSecond();
		} else {
			return new BigDecimal("0.0");
		}
	}

	@Override
	public LastUserListenPlayVo getLatelyTrack() {
		//获取用户登录的id
		Long userId = AuthContextHolder.getUserId();

		//创建分集合
		String connectionName = MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS,userId);
		Criteria criteria = Criteria.where("userId").is(userId);
		Query query = Query.query(criteria);
		query.with(Sort.by(Sort.Direction.DESC,"updateTime"));
		query.limit(1);
		//查询最近一次的播放进度
		UserListenProcess userListenProcess = mongoTemplate.findOne(query,UserListenProcess.class,connectionName);

		//构建响应数据
		LastUserListenPlayVo lastUserListenPlayVo = new LastUserListenPlayVo();

		if(userListenProcess!=null){
			lastUserListenPlayVo.setAlbumId(userListenProcess.getAlbumId());
			lastUserListenPlayVo.setTrackId(userListenProcess.getTrackId());
			return lastUserListenPlayVo ;
		}

		return lastUserListenPlayVo;
	}
}
